#pragma once
#include "interval_out_io.h"
#include "io_macro.h"
#include "io_sturct.h"
#include "io_factory.h"
// 最大模块数量，支持8个
#define MAX_MODULE_COUNT 8

// 读取模块参数的常量字符串
struct UnitName
{
    std::string num_digital_input;
    std::string num_digital_output;
    std::string num_analog_input;
    std::string num_analog_output;
    std::string interface_type;
    std::string modbus_slave_name;
    std::string can_port;
    std::string node_id;
    std::string start_addr;
    UnitName()
    {
        num_digital_input = "num_digital_input";
        num_digital_output = "num_digital_output";
        num_analog_input = "num_analog_input";
        num_analog_output = "num_analog_output";
        interface_type = "interface_type";
        modbus_slave_name = "modbus_slave_name";
        can_port = "can_port";
        node_id = "node_id";
        start_addr = "start_addr";
    }
};

namespace io_module {

class IoHardInterface
{
public:
    explicit IoHardInterface(const std::shared_ptr<rclcpp::Node>& node);

    ~IoHardInterface();

    bool init();

    // 读取输入io状态
    bool read_input_ios(const int &count_io, uint64_t &rets);

    // 设置间隔性输出
    bool set_interval_reg(SetFrequency &reg);

    // 读取模拟量输入状态
    bool read_inputsA(const int &count, std::vector<BaseInterface::WORD> &rets);

    // 设置单路模拟量输出
    bool set_outputsA(const int &index, const BaseInterface::WORD &raw_data);

private:
    // 节点句柄
    std::shared_ptr<rclcpp::Node> m_priNh;
    // 创建不同类型的io模块工厂
    IoFactory m_io_factory;
    // 参数表中配置的所有输入对象
    std::map<std::string, int> io_input_objects;
    // 参数表中配置的所有的输出对象
    std::map<std::string, IntervalOutIo> io_output_objects;
    // 线程互斥锁
    std::mutex m_mutex;
    // 模拟量输入互斥锁
    std::mutex m_readA_mutex;
    // 模拟量互输出斥锁
    std::mutex m_writeA_mutex;
    // 线程退出锁
    std::timed_mutex m_quit_mutex;
    // 线程
    std::thread m_thread;
    // 初始化标识
    bool m_init_ok;
    // 线程周期调用函数
    void cycle();
    // 循环输出io循环
    void output_io_cycle();
    // 静态线程函数
    static void thread_fun(IoHardInterface *pThis);
    // 设置单点输出
    bool set_output_io(const int &index, const bool &level);

    // 读取模块ros参数服务器字段
    bool read_module_param();

    // 读取参数服务器配置的io参数
    bool read_param_server();

    // 开始动态输出
    void start_output();

    // 停止动态输出
    void stop_output();
};
}
